from model.Teacher import Teacher
from model.Student import Student
from controller.Base import BaseHandler
from tornado import gen, concurrent
from concurrent.futures import ThreadPoolExecutor

from util import GenerateYzm


class LoginHandler(BaseHandler):
    executor = ThreadPoolExecutor(3)
    @gen.coroutine
    def get(self, *args, **kwargs):
        return self.render("login.html")

    @gen.coroutine
    def post(self, *args, **kwargs):
        try:
            a = self.get_argument("username")
            b = self.get_argument("password")
            c = self.get_argument("user_cate")
            # 0 stu; 1 tea; 2 admin
            d = self.get_argument("yzm")
        except Exception as e:
            return self.write(self.response_code.PARAM_NOT_COMPLETE)
        if not c.isdigit():
            return self.write(self.response_code.PARAM_TYPE_BIND_ERROR)
        if d.upper() != self.session["yzm"].upper():
            return self.write(self.response_code.YZM_IS_WRONG)
        c = int(c)

        login_result = False
        if c == 0:
            result = yield Student.get_by_id(a)
            if len(result) != 0 and b == result['pid'][-6:]:
                if result['face_exist'] == 0:
                    # 未注册
                    return self.write(self.response_code.USER_NOT_UPLOAD_FACE)
                self.session["id"] = a
                self.session["cate"] = 0
                self.session['name'] = result['name']
                self.session['class'] = result['class']
                self.session.save()
                login_result = True
        if c == 1:
            result = yield Teacher.get_by_id(a)
            if len(result) != 0 and b == "123456":
                self.session["id"] = a
                self.session['name'] = result['tname']
                self.session["cate"] = 1
                self.session.save()
                login_result = True

        if c == 2:
            result = (a == "admin" and b == "admin")
            if result:
                self.session["id"] = 0
                self.session['name'] = '管理员'
                self.session["cate"] = 2
                self.session.save()
                login_result = True

        if login_result:
            return self.write(self.response_code.SUCCESS)
        else:
            return self.write(self.response_code.USER_LOGIN_ERROR)

    @gen.coroutine
    def put(self, *args, **kwargs):
        # try:
        a = self.get_argument("username")
        s_id = self.get_argument("s_id")
        c = self.get_argument("s_pid")
        d = self.get_argument("yzm")
        img_file = self.get_argument("pid_img")
        # except Exception as e:
        #     return self.write(self.response_code.PARAM_NOT_COMPLETE)

        # 验证码确认
        if d.upper() != self.session.get("yzm").upper():
            return self.write(self.response_code.YZM_IS_WRONG)

        # 用户确认
        stu = yield Student.get_by_id(s_id)
        class_id = stu["class"]
        if not (len(stu) != 0 and a == stu["name"] and c.upper() == stu["pid"].upper()):
            return self.write(self.response_code.USER_LOGIN_ERROR)

        response = self.face_client.getUser(s_id, class_id)
        if response['error_code'] != 223103:
            return self.write(self.response_code.USER_HAS_EXISTED)

        # 解析照片,保存用户照片特征值
        try:
            result = yield self.save_to_database(s_id, class_id, img_file)
        except Exception as e:
            print(e)
            return self.write(self.response_code.SYSTEM_BUSY_ERROR)
        print(result)
        if result == 0:
            yield Student.update_face(s_id, 1)
            return self.write(self.response_code.SUCCESS)
        elif result == 223105:
            return self.write(self.response_code.USER_FACE_ERROR)
        else:
            return self.write(self.response_code.INTERFACE_REQUEST_TIMEOUT)

    @concurrent.run_on_executor
    def save_to_database(self, s_id, class_id, img_file_b64):
        """ 2.人脸注册 """
        options = {
            "user_info": "student",
            "quality_control": "NORMAL",
            "liveness_control": "LOW",
        }
        result = self.face_client.addUser(img_file_b64, "BASE64", class_id, s_id, options)
        print(result)
        return result['error_code']

    # @concurrent.run_on_executor
    # def save_to_database(self, s_id, img_file):
    #     fp = BytesIO(base64.b64decode(img_file))
    #     img = face_recognition.load_image_file(fp)
    #     img_encode = face_recognition.face_encodings(img)
    #     if len(img_encode) != 1:
    #         # 识别到的脸不为一
    #         return False
    #     yield Student.update_face(s_id, img_encode[0].dumps())
    #     return True

    @gen.coroutine
    def delete(self):
        self.session.exit()
        return self.write(self.response_code.SUCCESS)


class YzmHandler(BaseHandler):
    executor = ThreadPoolExecutor(2)

    @gen.coroutine
    def get(self):
        futures = GenerateYzm.generate(self)
        valid_str, data = "", ""
        for future in futures:
            valid_str, data = yield future
        self.session["yzm"] = valid_str  # 将随机字符串放入session中
        self.session.save()
        self.set_header("Content-type", "image/png")
        return self.write(data)
